home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / worn.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  9KB  |  332 lines

  1. /*    SCCS Id: @(#)worn.c    3.1    92/12/13
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. static void FDECL(rel_1_obj, (struct monst *,struct obj *));
  8.  
  9. const struct worn {
  10.     long w_mask;
  11.     struct obj **w_obj;
  12. } worn[] = {
  13.     { W_ARM, &uarm },
  14.     { W_ARMC, &uarmc },
  15.     { W_ARMH, &uarmh },
  16.     { W_ARMS, &uarms },
  17.     { W_ARMG, &uarmg },
  18.     { W_ARMF, &uarmf },
  19. #ifdef TOURIST
  20.     { W_ARMU, &uarmu },
  21. #endif
  22.     { W_RINGL, &uleft },
  23.     { W_RINGR, &uright },
  24.     { W_WEP, &uwep },
  25.     { W_AMUL, &uamul },
  26.     { W_TOOL, &ublindf },
  27.     { W_BALL, &uball },
  28.     { W_CHAIN, &uchain },
  29.     { 0, 0 }
  30. };
  31.  
  32. void
  33. setworn(obj, mask)
  34. register struct obj *obj;
  35. long mask;
  36. {
  37.     register const struct worn *wp;
  38.     register struct obj *oobj;
  39.  
  40.     for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
  41.         oobj = *(wp->w_obj);
  42.         if(oobj && !(oobj->owornmask & wp->w_mask))
  43.             impossible("Setworn: mask = %ld.", wp->w_mask);
  44.         if(oobj) {
  45.             oobj->owornmask &= ~wp->w_mask;
  46.             /* leave as "x = x <op> y", here and below, for broken
  47.              * compilers */
  48.             u.uprops[objects[oobj->otyp].oc_oprop].p_flgs = 
  49.                 u.uprops[objects[oobj->otyp].oc_oprop].p_flgs & 
  50.                 ~wp->w_mask;
  51.             if (oobj->oartifact) set_artifact_intrinsic(oobj, 0, mask);
  52.         }
  53.         *(wp->w_obj) = obj;
  54.         if(obj) {
  55.             obj->owornmask |= wp->w_mask;
  56.         /* prevent getting intrinsics from wielding potions, etc... */
  57.         /* wp_mask should be same as mask at this point */
  58.             if(obj->oclass == WEAPON_CLASS || mask != W_WEP) {
  59.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  60.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs | 
  61.                 wp->w_mask;
  62.             if (obj->oartifact) set_artifact_intrinsic(obj,1,mask);
  63.             } else if(obj->oartifact)
  64.             set_artifact_intrinsic(obj,1,mask);
  65.         }
  66.     }
  67. }
  68.  
  69. /* called e.g. when obj is destroyed */
  70. void
  71. setnotworn(obj)
  72. register struct obj *obj;
  73. {
  74.     register const struct worn *wp;
  75.  
  76.     if (!obj) return;
  77.     for(wp = worn; wp->w_mask; wp++)
  78.         if(obj == *(wp->w_obj)) {
  79.             *(wp->w_obj) = 0;
  80.             u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  81.                 u.uprops[objects[obj->otyp].oc_oprop].p_flgs & 
  82.                     ~wp->w_mask;
  83.             obj->owornmask &= ~wp->w_mask;
  84.             if (obj->oartifact)
  85.                 set_artifact_intrinsic(obj, 0, wp->w_mask);
  86.         }
  87. }
  88.  
  89. #ifdef MUSE
  90. int
  91. find_mac(mon)
  92. register struct monst *mon;
  93. {
  94.     register struct obj *obj;
  95.     int base = mon->data->ac;
  96.     long mwflags = mon->misc_worn_check;
  97.  
  98.     for(obj = mon->minvent; obj; obj = obj->nobj) {
  99.         if (obj->owornmask & mwflags)
  100.             base -= ARM_BONUS(obj);
  101.     }
  102.     return base;
  103. }
  104.  
  105. /* Wear first object of that type it finds, and never switch unless it
  106.  * has none at all.  This means that monsters with leather armor never
  107.  * switch to plate mail, but it also avoids the overhead of having seven
  108.  * struct obj *s for every monster in the game, more if we ever extend this.
  109.  */
  110. void
  111. m_dowear(mon, creation)
  112. register struct monst *mon;
  113. boolean creation;
  114. {
  115.     register struct obj *obj;
  116.  
  117.     /* Note the restrictions here are the same as in dowear in do_wear.c
  118.      * except for the additional restriction on intelligence.  (Players
  119.      * are always intelligent, even if polymorphed).
  120.      */
  121.     if (verysmall(mon->data) || nohands(mon->data)) return;
  122.     if (is_animal(mon->data) || mindless(mon->data)) return;
  123.  
  124.     for(obj = mon->minvent; obj; obj = obj->nobj) {
  125.         long flag;
  126.  
  127. # ifdef TOURIST
  128.         if (obj->otyp == HAWAIIAN_SHIRT) flag = W_ARMU;
  129.         else
  130. # endif
  131.         if (is_cloak(obj)) flag = W_ARMC;
  132.         else if (is_helmet(obj)) flag = W_ARMH;
  133.         else if (is_shield(obj)) {
  134.             if (MON_WEP(mon) && bimanual(MON_WEP(mon)))
  135.                 continue;
  136.             flag = W_ARMS;
  137.         } else if (is_gloves(obj)) {
  138.             if (MON_WEP(mon) && MON_WEP(mon)->cursed)
  139.                 continue;
  140.             flag = W_ARMG;
  141.         } else if (is_boots(obj)) flag = W_ARMF;
  142.         else if (obj->oclass == ARMOR_CLASS) {
  143. #ifdef POLYSELF
  144.             if (cantweararm(mon->data))
  145.                 continue;
  146. #endif
  147.             flag = W_ARM;
  148.         } else continue;
  149.         if (mon->misc_worn_check & flag) continue;
  150.             /* already wearing one */
  151.         if (!creation && canseemon(mon)) {
  152.             pline("%s puts on %s.", Monnam(mon),
  153.                         distant_name(obj, doname));
  154.             mon->mfrozen = objects[obj->otyp].oc_delay;
  155.             if (mon->mfrozen) mon->mcanmove = 0;
  156.         }
  157.         mon->misc_worn_check |= flag;
  158.         obj->owornmask |= flag;
  159.     }
  160. }
  161.  
  162. struct obj *
  163. which_armor(mon, flag)
  164. struct monst *mon;
  165. long flag;
  166. {
  167.     register struct obj *obj;
  168.  
  169.     for(obj = mon->minvent; obj; obj = obj->nobj)
  170.         if (obj->owornmask & flag) return obj;
  171.     return((struct obj *)0);
  172. }
  173.  
  174. static void
  175. rel_1_obj(mon, obj)
  176. struct monst *mon;
  177. struct obj *obj;
  178. {
  179.     struct obj *otmp;
  180.     struct obj *backobj = (struct obj *)0;
  181.  
  182.     for(otmp = mon->minvent; otmp; otmp = otmp->nobj) {
  183.         if (obj == otmp) {
  184.             if (!backobj) mon->minvent = otmp->nobj;
  185.             else backobj->nobj = otmp->nobj;
  186.             place_object(otmp, mon->mx, mon->my);
  187.             otmp->nobj = fobj;
  188.             fobj = otmp;
  189.             if (cansee(mon->mx, mon->my)) newsym(mon->mx, mon->my);
  190.             return;
  191.         }
  192.         backobj = otmp;
  193.     }
  194.     impossible("%s has %s missing?", Monnam(mon), xname(obj));
  195. }
  196.  
  197. void
  198. mon_break_armor(mon)
  199. struct monst *mon;
  200. {
  201.     register struct obj *otmp;
  202.     struct permonst *mdat = mon->data;
  203.     boolean vis = cansee(mon->mx, mon->my);
  204.     const char *pronoun, *ppronoun;
  205.  
  206.     switch(gender(mon)) {
  207.         case 0: pronoun = "him"; ppronoun = "his"; break;
  208.         case 1: pronoun = ppronoun = "her"; break;
  209.         default: pronoun = "it"; ppronoun = "its"; break;
  210.     }
  211.     if (breakarm(mdat)) {
  212.         if (otmp = which_armor(mon, W_ARM)) {
  213.         if (vis)
  214.             pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
  215.         else
  216.             You("hear a cracking sound.");
  217.         mon->misc_worn_check &= ~W_ARM;
  218.         m_useup(mon, otmp);
  219.         }
  220.         if (otmp = which_armor(mon, W_ARMC)) {
  221.         if (otmp->oartifact) {
  222.             if (vis)
  223.             pline("%s cloak falls off!", s_suffix(Monnam(mon)));
  224.             mon->misc_worn_check &= ~W_ARMC;
  225.             otmp->owornmask &= ~W_ARMC;
  226.             rel_1_obj(mon, otmp);
  227.         } else {
  228.             if (vis)
  229.             pline("%s cloak tears apart!", s_suffix(Monnam(mon)));
  230.             else
  231.             You("hear a ripping sound.");
  232.             mon->misc_worn_check &= ~W_ARMC;
  233.             m_useup(mon, otmp);
  234.         }
  235.         }
  236. # ifdef TOURIST
  237.         if (otmp = which_armor(mon, W_ARMU)) {
  238.         if (vis)
  239.             pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
  240.         else
  241.             You("hear a ripping sound.");
  242.         mon->misc_worn_check &= ~W_ARMU;
  243.         m_useup(mon, otmp);
  244.         }
  245. # endif
  246.         } else if (sliparm(mdat)) {
  247.         if (otmp = which_armor(mon, W_ARM)) {
  248.         if (vis)
  249.             pline("%s armor falls around %s!", 
  250.                      s_suffix(Monnam(mon)), pronoun);
  251.         else
  252.             You("hear a thud.");
  253.         mon->misc_worn_check &= ~W_ARM;
  254.         otmp->owornmask &= ~W_ARM;
  255.         rel_1_obj(mon, otmp);
  256.         }
  257.         if (otmp = which_armor(mon, W_ARMC)) {
  258.         if (vis)
  259.             if (is_whirly(mon->data))
  260.             pline("%s cloak falls, unsupported!", 
  261.                          s_suffix(Monnam(mon)));
  262.             else
  263.             pline("%s shrinks out of %s cloak!", Monnam(mon),
  264.                                 ppronoun);
  265.         mon->misc_worn_check &= ~W_ARMC;
  266.         otmp->owornmask &= ~W_ARMC;
  267.         rel_1_obj(mon, otmp);
  268.         }
  269. # ifdef TOURIST
  270.         if (otmp = which_armor(mon, W_ARMU)) {
  271.         if (vis)
  272.             if (sliparm(mon->data))
  273.             pline("%s seeps right through %s shirt!",
  274.                     Monnam(mon), ppronoun);
  275.             else
  276.             pline("%s becomes much too small for %s shirt!",
  277.                     Monnam(mon), ppronoun);
  278.         mon->misc_worn_check &= ~W_ARMU;
  279.         otmp->owornmask &= ~W_ARMU;
  280.         rel_1_obj(mon, otmp);
  281.         }
  282. # endif
  283.     }
  284.     if (nohands(mdat) || verysmall(mdat)) {
  285.         if (otmp = which_armor(mon, W_ARMG)) {
  286.         if (vis)
  287.             pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
  288.                     MON_WEP(mon) ? " and weapon" : "");
  289.         possibly_unwield(mon);
  290.         mon->misc_worn_check &= ~W_ARMG;
  291.         otmp->owornmask &= ~W_ARMG;
  292.         rel_1_obj(mon, otmp);
  293.         }
  294.         if (otmp = which_armor(mon, W_ARMS)) {
  295.         if (vis)
  296.             pline("%s can no longer hold %s shield!", Monnam(mon),
  297.                                 ppronoun);
  298.         else
  299.             You("hear a clank.");
  300.         mon->misc_worn_check &= ~W_ARMS;
  301.         otmp->owornmask &= ~W_ARMS;
  302.         rel_1_obj(mon, otmp);
  303.         }
  304.         if (otmp = which_armor(mon, W_ARMH)) {
  305.         if (vis)
  306.             pline("%s helmet falls to the floor!", 
  307.                        s_suffix(Monnam(mon)));
  308.         else
  309.             You("hear a clank.");
  310.         mon->misc_worn_check &= ~W_ARMH;
  311.         otmp->owornmask &= ~W_ARMH;
  312.         rel_1_obj(mon, otmp);
  313.         }
  314.         if (otmp = which_armor(mon, W_ARMF)) {
  315.         if (vis) {
  316.             if (is_whirly(mon->data))
  317.             pline("%s boots fall away!", 
  318.                            s_suffix(Monnam(mon)));
  319.             else pline("%s boots %s off %s feet!", 
  320.             s_suffix(Monnam(mon)),
  321.             verysmall(mdat) ? "slide" : "are pushed", ppronoun);
  322.         }
  323.         mon->misc_worn_check &= ~W_ARMF;
  324.         otmp->owornmask &= ~W_ARMF;
  325.         rel_1_obj(mon, otmp);
  326.         }
  327.     }
  328. }
  329. #endif
  330.  
  331. /*worn.c*/
  332.